"""
正则表达式和随机数据生成工具

提供各种随机数据生成和正则替换功能，用于测试数据准备和请求参数处理
"""

import re
import random
from datetime import date, timedelta, datetime
from jsonpath_ng import parse
from faker import Faker
from autoapi.common.log import log

class Context:
    """正则替换"""

    def __init__(self):
        self.faker = Faker(locale="zh_CN")

    @classmethod
    def random_int(cls, min, max) -> int:
        """
        :return: 随机数
        """
        _data = random.randint(int(min), int(max))
        return _data

    def get_phone(self) -> str:
        """随机生成中国大陆手机号码
        
        Returns:
            str: 符合中国大陆手机号格式的随机号码
        """
        phone = self.faker.phone_number()
        return phone

    def get_id_number(self) -> str:
        """随机生成中国大陆身份证号码
        
        Returns:
            str: 符合中国大陆身份证格式的随机号码
        """
        id_number = self.faker.ssn()
        return id_number

    def get_female_name(self) -> str:
        """

        :return: 女生姓名
        """
        female_name = self.faker.name_female()
        return female_name

    def get_male_name(self) -> str:
        """
        :return: 男生姓名
        """
        male_name = self.faker.name_male()
        return male_name

    def get_email(self) -> str:
        """

        :return: 生成邮箱
        """
        email = self.faker.email()
        return email

    @classmethod
    def get_time(cls) -> str:
        """
        计算当前时间
        :return:
        """
        now_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        return now_time

    @classmethod
    def today_date(cls):
        """获取今日0点整时间"""

        _today = date.today().strftime("%Y-%m-%d") + " 00:00:00"
        return str(_today)

    @classmethod
    def time_after_week(cls):
        """获取一周后12点整的时间"""

        _time_after_week = (date.today() + timedelta(days=+6)).strftime(
            "%Y-%m-%d"
        ) + " 00:00:00"
        return _time_after_week


def sql_json(js_path, res):
    """提取 sql中的 json 数据"""
    jsonpath_expr = parse(js_path)
    result = [match.value for match in jsonpath_expr.find(res)]
    if not result:
        raise ValueError(f"sql中的jsonpath获取失败 {res}, {js_path}")
    _json_data = result[0]
    return _json_data


def sql_regular(value, res=None):
    """
    这里处理sql中的依赖数据，通过获取接口响应的jsonpath的值进行替换
    :param res: jsonpath使用的返回结果
    :param value:
    :return:
    """
    sql_json_list = re.findall(r"\$json\((.*?)\)\$", value)

    for i in sql_json_list:
        pattern = re.compile(
            r"\$json\(" + i.replace("$", "\\$").replace("[", "\\[") + r"\)\$"
        )
        key = str(sql_json(i, res))
        value = re.sub(pattern, key, value, count=1)

    return value


def regular(target: str) -> str:
    """使用正则表达式替换请求数据中的标记
    
    支持格式: ${{function_name(param1,param2)}}
    
    Args:
        target (str): 需要处理的字符串
        
    Returns:
        str: 替换后的字符串
        
    Raises:
        AttributeError: 当找不到对应的替换方法时
        IndexError: 当函数语法不正确时
    """
    try:
        regular_pattern = r"\${{(.*?)}}"
        while re.findall(regular_pattern, target):
            match = re.search(regular_pattern, target)
            if not match:
                break
            key = match.group(1)
            value_types = ["int:", "bool:", "list:", "dict:", "tuple:", "float:"]
            if any(i in key for i in value_types) is True:
                func_name = key.split(":")[1].split("(")[0]
                value_name = key.split(":")[1].split("(")[1][:-1]
                if value_name == "":
                    value_data = getattr(Context(), func_name)()
                else:
                    value_data = getattr(Context(), func_name)(*value_name.split(","))
                regular_int_pattern = r"\'\${{(.*?)}}\'"
                target = re.sub(regular_int_pattern, str(value_data), target, 1)
            else:
                func_name = key.split("(")[0]
                value_name = key.split("(")[1][:-1]
                if value_name == "":
                    value_data = getattr(Context(), func_name)()
                else:
                    value_data = getattr(Context(), func_name)(*value_name.split(","))
                target = re.sub(regular_pattern, str(value_data), target, 1)
        return target

    except AttributeError:
        log.error("未找到对应的替换的数据, 请检查数据是否正确 %s", target)
        raise
    except IndexError:
        log.error("yaml中的 ${{}} 函数方法不正确，正确语法 ${{方法名()}} 示例：${{current_time()}}")
        raise


if __name__ == "__main__":
    # 测试代码示例
    e = "${{Ctest01(0)}}"  # None
    a = "${{Ctest02()}}"  # shuchu2
    b = "${{Ctest03(0,1)}}"  # 啥也没有
    d = "${{host()}} aaa"  # http://127.0.0.1:8000 aaa
    E = regular(e)
    A = regular(a)
    B = regular(b)
    D = regular(d)
    # 测试时取消注释下面的print语句
    # print(E, A, B, D)
